package roaring

import (
	
	
)

type bitmapContainer struct {
	cardinality int
	bitmap      []uint64
}

func ( bitmapContainer) () string {
	var  string
	for  := .getShortIterator(); .hasNext(); {
		 += fmt.Sprintf("%v, ", .next())
	}
	return 
}

func newBitmapContainer() *bitmapContainer {
	 := new(bitmapContainer)
	 := (1 << 16) / 64
	.bitmap = make([]uint64, , )
	return 
}

func newBitmapContainerwithRange(,  int) *bitmapContainer {
	 := newBitmapContainer()
	.cardinality =  -  + 1
	if .cardinality == maxCapacity {
		fill(.bitmap, uint64(0xffffffffffffffff))
	} else {
		 :=  / 64
		 :=  / 64
		 := uint64( & 63)
		 := uint64(63 - ( & 63))

		fillRange(.bitmap, , +1, uint64(0xffffffffffffffff))
		.bitmap[] ^= ((uint64(1) << ) - 1)
		 := (uint64(1) << ) - 1
		 :=  << (uint64(64) - )
		.bitmap[] ^= 
	}
	return 
}

func ( *bitmapContainer) () uint16 {
	for  := 0;  < len(.bitmap); ++ {
		 := .bitmap[]
		if  != 0 {
			 := countTrailingZeros()
			return uint16( + *64)
		}
	}
	return MaxUint16
}

// i should be non-zero
func clz( uint64) int {
	 := 1
	 := uint32( >> 32)
	if  == 0 {
		 += 32
		 = uint32()
	}
	if >>16 == 0 {
		 += 16
		 =  << 16
	}
	if >>24 == 0 {
		 += 8
		 =  << 8
	}
	if >>28 == 0 {
		 += 4
		 =  << 4
	}
	if >>30 == 0 {
		 += 2
		 =  << 2
	}
	return  - int(>>31)
}

func ( *bitmapContainer) () uint16 {
	for  := len(.bitmap);  > 0; -- {
		 := .bitmap[-1]
		if  != 0 {
			 := clz()
			return uint16((-1)*64 + 63 - )
		}
	}
	return uint16(0)
}

func ( *bitmapContainer) ( func( uint16) bool) bool {
	 := bitmapContainerShortIterator{, .NextSetBit(0)}

	for .hasNext() {
		if !(.next()) {
			return false
		}
	}

	return true
}

type bitmapContainerShortIterator struct {
	ptr *bitmapContainer
	i   int
}

func ( *bitmapContainerShortIterator) () uint16 {
	 := .i
	.i = .ptr.NextSetBit(uint(.i) + 1)
	return uint16()
}
func ( *bitmapContainerShortIterator) () bool {
	return .i >= 0
}

func ( *bitmapContainerShortIterator) () uint16 {
	return uint16(.i)
}

func ( *bitmapContainerShortIterator) ( uint16) {
	if .hasNext() && .peekNext() <  {
		.i = .ptr.NextSetBit(uint())
	}
}

func newBitmapContainerShortIterator( *bitmapContainer) *bitmapContainerShortIterator {
	return &bitmapContainerShortIterator{, .NextSetBit(0)}
}

func ( *bitmapContainer) () shortPeekable {
	return newBitmapContainerShortIterator()
}

type reverseBitmapContainerShortIterator struct {
	ptr *bitmapContainer
	i   int
}

func ( *reverseBitmapContainerShortIterator) () uint16 {
	if .i == -1 {
		panic("reverseBitmapContainerShortIterator.next() going beyond what is available")
	}

	 := .i
	.i = .ptr.PrevSetBit(.i - 1)
	return uint16()
}

func ( *reverseBitmapContainerShortIterator) () bool {
	return .i >= 0
}

func newReverseBitmapContainerShortIterator( *bitmapContainer) *reverseBitmapContainerShortIterator {
	if .cardinality == 0 {
		return &reverseBitmapContainerShortIterator{, -1}
	}
	return &reverseBitmapContainerShortIterator{, int(.maximum())}
}

func ( *bitmapContainer) () shortIterable {
	return newReverseBitmapContainerShortIterator()
}

type bitmapContainerManyIterator struct {
	ptr    *bitmapContainer
	base   int
	bitset uint64
}

func ( *bitmapContainerManyIterator) ( uint32,  []uint32) int {
	 := 0
	 := .base
	 := .bitset

	for  < len() {
		if  == 0 {
			++
			if  >= len(.ptr.bitmap) {
				.base = 
				.bitset = 
				return 
			}
			 = .ptr.bitmap[]
			continue
		}
		 :=  & -
		[] = uint32((( * 64) + int(popcount(-1)))) | 
		 =  + 1
		 ^= 
	}

	.base = 
	.bitset = 
	return 
}

func ( *bitmapContainerManyIterator) ( uint64,  []uint64) int {
	 := 0
	 := .base
	 := .bitset

	for  < len() {
		if  == 0 {
			++
			if  >= len(.ptr.bitmap) {
				.base = 
				.bitset = 
				return 
			}
			 = .ptr.bitmap[]
			continue
		}
		 :=  & -
		[] = uint64((( * 64) + int(popcount(-1)))) | 
		 =  + 1
		 ^= 
	}

	.base = 
	.bitset = 
	return 
}

func newBitmapContainerManyIterator( *bitmapContainer) *bitmapContainerManyIterator {
	return &bitmapContainerManyIterator{, -1, 0}
}

func ( *bitmapContainer) () manyIterable {
	return newBitmapContainerManyIterator()
}

func ( *bitmapContainer) () int {
	return len(.bitmap) * 8 // + bcBaseBytes
}

func ( *bitmapContainer) () int {
	//return bc.Msgsize()// NOO! This breaks GetSerializedSizeInBytes
	return len(.bitmap) * 8
}

const bcBaseBytes = int(unsafe.Sizeof(bitmapContainer{}))

// bitmapContainer doesn't depend on card, always fully allocated
func bitmapContainerSizeInBytes() int {
	return bcBaseBytes + (1<<16)/8
}

func bitmapEquals(,  []uint64) bool {
	if len() != len() {
		return false
	}
	for ,  := range  {
		if  != [] {
			return false
		}
	}
	return true
}

func ( *bitmapContainer) ( []uint32,  int,  uint32) int {
	// TODO: should be written as optimized assembly
	 := 
	 := 
	for  := 0;  < len(.bitmap); ++ {
		 := .bitmap[]
		for  != 0 {
			 :=  & -
			[] =  + uint32(popcount(-1))
			++
			 ^= 
		}
		 += 64
	}
	return 
}

func ( *bitmapContainer) ( container) bool {
	,  := .(*bitmapContainer)
	if  {
		if .cardinality != .cardinality {
			return false
		}
		return bitmapEquals(.bitmap, .bitmap)
	}

	// use generic comparison
	if .getCardinality() != .getCardinality() {
		return false
	}
	 := .getShortIterator()
	 := .getShortIterator()

	for .hasNext() {
		if .next() != .next() {
			return false
		}
	}
	return true
}

func ( *bitmapContainer) ( uint16) container {
	.iadd()
	if .isFull() {
		return newRunContainer16Range(0, MaxUint16)
	}
	return 
}

func ( *bitmapContainer) ( uint16) bool {
	 := int()
	 := .bitmap[/64]
	 := uint64(1) << (uint() % 64)
	 :=  | 
	.bitmap[/64] = 
	.cardinality += int(( ^ ) >> (uint() % 64))
	return  != 
}

func ( *bitmapContainer) ( uint16) container {
	if .iremove() {
		if .cardinality == arrayDefaultMaxSize {
			return .toArrayContainer()
		}
	}
	return 
}

// iremove returns true if i was found.
func ( *bitmapContainer) ( uint16) bool {
	if .contains() {
		.cardinality--
		.bitmap[/64] &^= (uint64(1) << ( % 64))
		return true
	}
	return false
}

func ( *bitmapContainer) () bool {
	return .cardinality == int(MaxUint16)+1
}

func ( *bitmapContainer) () int {
	return .cardinality
}

func ( *bitmapContainer) () bool {
	return .cardinality == 0
}

func ( *bitmapContainer) () container {
	 := bitmapContainer{.cardinality, make([]uint64, len(.bitmap))}
	copy(.bitmap, .bitmap[:])
	return &
}

// add all values in range [firstOfRange,lastOfRange)
func ( *bitmapContainer) (,  int) container {
	.cardinality += setBitmapRangeAndCardinalityChange(.bitmap, , )
	return 
}

// remove all values in range [firstOfRange,lastOfRange)
func ( *bitmapContainer) (,  int) container {
	.cardinality += resetBitmapRangeAndCardinalityChange(.bitmap, , )
	if .getCardinality() <= arrayDefaultMaxSize {
		return .toArrayContainer()
	}
	return 
}

// flip all values in range [firstOfRange,endx)
func ( *bitmapContainer) (,  int) container {
	if - == maxCapacity {
		flipBitmapRange(.bitmap, , )
		.cardinality = maxCapacity - .cardinality
	} else if - > maxCapacity/2 {
		flipBitmapRange(.bitmap, , )
		.computeCardinality()
	} else {
		.cardinality += flipBitmapRangeAndCardinalityChange(.bitmap, , )
	}
	if .getCardinality() <= arrayDefaultMaxSize {
		return .toArrayContainer()
	}
	return 
}

// flip all values in range [firstOfRange,endx)
func ( *bitmapContainer) (,  int) container {
	 := .clone()
	return .inot(, )
}

func ( *bitmapContainer) ( container) container {
	switch x := .(type) {
	case *arrayContainer:
		return .orArray()
	case *bitmapContainer:
		return .orBitmap()
	case *runContainer16:
		if .isFull() {
			return .clone()
		}
		return .orBitmapContainer()
	}
	panic("unsupported container type")
}

func ( *bitmapContainer) ( container) int {
	switch x := .(type) {
	case *arrayContainer:
		return .orArrayCardinality()
	case *bitmapContainer:
		return .orBitmapCardinality()
	case *runContainer16:
		return .orBitmapContainerCardinality()
	}
	panic("unsupported container type")
}

func ( *bitmapContainer) ( container) container {
	switch x := .(type) {
	case *arrayContainer:
		return .iorArray()
	case *bitmapContainer:
		return .iorBitmap()
	case *runContainer16:
		if .isFull() {
			return .clone()
		}
		for  := range .iv {
			.iaddRange(int(.iv[].start), int(.iv[].last())+1)
		}
		if .isFull() {
			return newRunContainer16Range(0, MaxUint16)
		}
		//bc.computeCardinality()
		return 
	}
	panic(fmt.Errorf("unsupported container type %T", ))
}

func ( *bitmapContainer) ( container) container {
	switch x := .(type) {
	case *arrayContainer:
		return .lazyIORArray()
	case *bitmapContainer:
		return .lazyIORBitmap()
	case *runContainer16:
		if .isFull() {
			return .clone()
		}

		// Manually inlined setBitmapRange function
		 := .bitmap
		for ,  := range .iv {
			 := int(.start)
			 := int(.last()) + 1
			if  >=  {
				continue
			}
			 :=  / 64
			 := ( - 1) / 64
			if  ==  {
				[] |= (^uint64(0) << uint(%64)) & (^uint64(0) >> (uint(-) % 64))
				continue
			}
			[] |= ^uint64(0) << uint(%64)
			for  :=  + 1;  < ; ++ {
				[] = ^uint64(0)
			}
			[] |= ^uint64(0) >> (uint(-) % 64)
		}
		.cardinality = invalidCardinality
		return 
	}
	panic("unsupported container type")
}

func ( *bitmapContainer) ( container) container {
	switch x := .(type) {
	case *arrayContainer:
		return .lazyORArray()
	case *bitmapContainer:
		return .lazyORBitmap()
	case *runContainer16:
		if .isFull() {
			return .clone()
		}
		// TODO: implement lazy OR
		return .orBitmapContainer()

	}
	panic("unsupported container type")
}

func ( *bitmapContainer) ( *arrayContainer) container {
	 := .clone().(*bitmapContainer)
	 := .getCardinality()
	for  := 0;  < ; ++ {
		 := .content[]
		 := uint() >> 6
		 := .bitmap[]
		 :=  | (uint64(1) << ( % 64))
		.bitmap[] = 
		.cardinality += int(( - ) >> 63)
	}
	return 
}

func ( *bitmapContainer) ( *arrayContainer) int {
	 := 0
	 := .getCardinality()
	for  := 0;  < ; ++ {
		// branchless:
		 := .content[]
		 := uint() >> 6
		 := .bitmap[]
		 :=  | (uint64(1) << ( % 64))
		 += int(( - ) >> 63)
	}
	return 
}

func ( *bitmapContainer) ( *bitmapContainer) container {
	 := newBitmapContainer()
	for  := 0;  < len(.bitmap); ++ {
		.bitmap[] = .bitmap[] | .bitmap[]
	}
	.computeCardinality()
	if .isFull() {
		return newRunContainer16Range(0, MaxUint16)
	}
	return 
}

func ( *bitmapContainer) ( *bitmapContainer) int {
	return int(popcntOrSlice(.bitmap, .bitmap))
}

func ( *bitmapContainer) ( *bitmapContainer) int {
	return int(popcntAndSlice(.bitmap, .bitmap))
}

func ( *bitmapContainer) () {
	.cardinality = int(popcntSlice(.bitmap))
}

func ( *bitmapContainer) ( *arrayContainer) container {
	for  := range .content {
		 := .content[]
		 := uint() >> 6
		 := .bitmap[]
		 :=  | (uint64(1) << ( % 64))
		.bitmap[] = 
		.cardinality += int(( - ) >> 63)
	}
	if .isFull() {
		return newRunContainer16Range(0, MaxUint16)
	}
	return 
}

func ( *bitmapContainer) ( *bitmapContainer) container {
	 := 
	.cardinality = 0
	for  := 0;  < len(.bitmap); ++ {
		.bitmap[] = .bitmap[] | .bitmap[]
	}
	.computeCardinality()
	if .isFull() {
		return newRunContainer16Range(0, MaxUint16)
	}
	return 
}

func ( *bitmapContainer) ( *arrayContainer) container {
	 := 
	 := .getCardinality()
	for  := 0; +3 < ;  += 4 {
		 := (*[4]uint16)(unsafe.Pointer(&.content[]))
		 := [0]
		 := uint() >> 6
		.bitmap[] = .bitmap[] | (uint64(1) << ( % 64))

		 := [1]
		 := uint() >> 6
		.bitmap[] = .bitmap[] | (uint64(1) << ( % 64))

		 := [2]
		 := uint() >> 6
		.bitmap[] = .bitmap[] | (uint64(1) << ( % 64))

		 := [3]
		 := uint() >> 6
		.bitmap[] = .bitmap[] | (uint64(1) << ( % 64))
	}

	for  :=  &^ 3;  < ; ++ {
		 := .content[]
		 := uint() >> 6
		.bitmap[] = .bitmap[] | (uint64(1) << ( % 64))
	}

	.cardinality = invalidCardinality
	return 
}

func ( *bitmapContainer) ( *arrayContainer) container {
	 := .clone().(*bitmapContainer)
	return .lazyIORArray()
}

func ( *bitmapContainer) ( *bitmapContainer) container {
	 := 
	for  := 0;  < len(.bitmap); ++ {
		.bitmap[] = .bitmap[] | .bitmap[]
	}
	.cardinality = invalidCardinality
	return 
}

func ( *bitmapContainer) ( *bitmapContainer) container {
	 := .clone().(*bitmapContainer)
	return .lazyIORBitmap()
}

func ( *bitmapContainer) ( container) container {
	switch x := .(type) {
	case *arrayContainer:
		return .xorArray()
	case *bitmapContainer:
		return .xorBitmap()
	case *runContainer16:
		return .xorBitmap()
	}
	panic("unsupported container type")
}

func ( *bitmapContainer) ( *arrayContainer) container {
	 := .clone().(*bitmapContainer)
	 := .getCardinality()
	for  := 0;  < ; ++ {
		 := .content[]
		 := uint() >> 6
		 := .bitmap[]
		 := uint64(1) << ( % 64)
		.cardinality += 1 - 2*int((&)>>(%64))
		.bitmap[] =  ^ 
	}
	if .cardinality <= arrayDefaultMaxSize {
		return .toArrayContainer()
	}
	return 
}

func ( *bitmapContainer) ( uint16) int {
	// TODO: rewrite in assembly
	 := (uint() + 1) & 63
	if  == 0 {
		return int(popcntSlice(.bitmap[:(uint()+1)/64]))
	}
	return int(popcntSlice(.bitmap[:(uint()+1)/64]) + popcount(.bitmap[(uint()+1)/64]<<(64-)))
}

func ( *bitmapContainer) ( uint16) int {
	 := 
	for  := 0;  < len(.bitmap); ++ {
		 := popcount(.bitmap[])
		if uint16() >  {
			return *64 + selectBitPosition(.bitmap[], int())
		}
		 -= uint16()
	}
	return -1
}

func ( *bitmapContainer) ( *bitmapContainer) container {
	 := int(popcntXorSlice(.bitmap, .bitmap))

	if  > arrayDefaultMaxSize {
		 := newBitmapContainer()
		for  := 0;  < len(.bitmap); ++ {
			.bitmap[] = .bitmap[] ^ .bitmap[]
		}
		.cardinality = 
		if .isFull() {
			return newRunContainer16Range(0, MaxUint16)
		}
		return 
	}
	 := newArrayContainerSize()
	fillArrayXOR(.content, .bitmap, .bitmap)
	.content = .content[:]
	return 
}

func ( *bitmapContainer) ( container) container {
	switch x := .(type) {
	case *arrayContainer:
		return .andArray()
	case *bitmapContainer:
		return .andBitmap()
	case *runContainer16:
		if .isFull() {
			return .clone()
		}
		return .andBitmapContainer()
	}
	panic("unsupported container type")
}

func ( *bitmapContainer) ( container) int {
	switch x := .(type) {
	case *arrayContainer:
		return .andArrayCardinality()
	case *bitmapContainer:
		return .andBitmapCardinality()
	case *runContainer16:
		return .andBitmapContainerCardinality()
	}
	panic("unsupported container type")
}

func ( *bitmapContainer) ( container) bool {
	switch x := .(type) {
	case *arrayContainer:
		return .intersectsArray()
	case *bitmapContainer:
		return .intersectsBitmap()
	case *runContainer16:
		return .intersects()

	}
	panic("unsupported container type")
}

func ( *bitmapContainer) ( container) container {
	switch x := .(type) {
	case *arrayContainer:
		return .iandArray()
	case *bitmapContainer:
		return .iandBitmap()
	case *runContainer16:
		if .isFull() {
			return .clone()
		}
		return .iandRun16()
	}
	panic("unsupported container type")
}

func ( *bitmapContainer) ( *runContainer16) container {
	 := newBitmapContainerFromRun()
	return .iandBitmap()
}

func ( *bitmapContainer) ( *arrayContainer) container {
	 := .toBitmapContainer()
	return .iandBitmap()
}

func ( *bitmapContainer) ( *arrayContainer) *arrayContainer {
	 := newArrayContainerCapacity(len(.content))
	.content = .content[:cap(.content)]
	 := .getCardinality()
	 := 0
	for  := 0;  < ; ++ {
		 := .content[]
		.content[] = 
		 += int(.bitValue())
	}
	.content = .content[:]
	return 
}

func ( *bitmapContainer) ( *arrayContainer) int {
	 := .getCardinality()
	 := 0
	for  := 0;  < ; ++ {
		 := .content[]
		 += int(.bitValue())
	}
	return 
}

func ( *bitmapContainer) (,  uint) int {
	if  >=  {
		return 0
	}
	 :=  / 64
	 := ( - 1) / 64
	const  = ^uint64(0)
	if  ==  {
		return int(popcount(.bitmap[] & (( << ( % 64)) & ( >> ((64 - ) & 63)))))
	}
	 := popcount(.bitmap[] & ( << ( % 64)))
	 += popcntSlice(.bitmap[+1 : ])
	 += popcount(.bitmap[] & ( >> ((64 - ) & 63)))
	return int()
}

func ( *bitmapContainer) ( *bitmapContainer) container {
	 := int(popcntAndSlice(.bitmap, .bitmap))
	if  > arrayDefaultMaxSize {
		 := newBitmapContainer()
		for  := 0;  < len(.bitmap); ++ {
			.bitmap[] = .bitmap[] & .bitmap[]
		}
		.cardinality = 
		return 
	}
	 := newArrayContainerSize()
	fillArrayAND(.content, .bitmap, .bitmap)
	.content = .content[:] //not sure why i need this
	return 

}

func ( *bitmapContainer) ( *arrayContainer) bool {
	 := .getCardinality()
	for  := 0;  < ; ++ {
		 := .content[]
		if .contains() {
			return true
		}
	}
	return false
}

func ( *bitmapContainer) ( *bitmapContainer) bool {
	for  := 0;  < len(.bitmap); ++ {
		if (.bitmap[] & .bitmap[]) != 0 {
			return true
		}
	}
	return false

}

func ( *bitmapContainer) ( *bitmapContainer) container {
	 := int(popcntAndSlice(.bitmap, .bitmap))
	for  := 0;  < len(.bitmap); ++ {
		.bitmap[] = .bitmap[] & .bitmap[]
	}
	.cardinality = 

	if  <= arrayDefaultMaxSize {
		return newArrayContainerFromBitmap()
	}
	return 
}

func ( *bitmapContainer) ( container) container {
	switch x := .(type) {
	case *arrayContainer:
		return .andNotArray()
	case *bitmapContainer:
		return .andNotBitmap()
	case *runContainer16:
		return .andNotRun16()
	}
	panic("unsupported container type")
}

func ( *bitmapContainer) ( *runContainer16) container {
	 := .toBitmapContainer()
	return .andNotBitmap()
}

func ( *bitmapContainer) ( container) container {
	switch x := .(type) {
	case *arrayContainer:
		return .iandNotArray()
	case *bitmapContainer:
		return .iandNotBitmapSurely()
	case *runContainer16:
		return .iandNotRun16()
	}
	panic("unsupported container type")
}

func ( *bitmapContainer) ( *arrayContainer) container {
	if .isEmpty() || .isEmpty() {
		// Nothing to do.
		return 
	}

	// Word by word, we remove the elements in ac from bc. The approach is to build
	// a mask of the elements to remove, and then apply it to the bitmap.
	 := uint16(0)
	 := uint64(0)
	for ,  := range .content {
		if /64 !=  {
			// Flush the current word.
			if  != 0 {
				// We're removing bits that are set in the mask and in the current word.
				// To figure out the cardinality change, we count the number of bits that
				// are set in the mask and in the current word.
				 &= .bitmap[]
				.bitmap[] &= ^
				.cardinality -= int(popcount())
			}

			 =  / 64
			 = 0
		}
		 |= 1 << ( % 64)
	}

	// Flush the last word.
	 &= .bitmap[]
	.bitmap[] &= ^
	.cardinality -= int(popcount())

	if .getCardinality() <= arrayDefaultMaxSize {
		return .toArrayContainer()
	}
	return 
}

func ( *bitmapContainer) ( *runContainer16) container {
	if .isEmpty() || .isEmpty() {
		// Nothing to do.
		return 
	}

	 := .iv[0].start / 64
	 := (.iv[len(.iv)-1].last()) / 64 // inclusive

	 := popcntSlice(.bitmap[ : +1]) // before cardinality - after cardinality (for word range)

	for ,  := range .iv {
		resetBitmapRange(.bitmap, int(.start), int(.last())+1)
	}

	 -= popcntSlice(.bitmap[ : +1])

	.cardinality -= int()

	if .getCardinality() <= arrayDefaultMaxSize {
		return .toArrayContainer()
	}
	return 
}

func ( *bitmapContainer) ( *arrayContainer) container {
	 := .clone().(*bitmapContainer)
	 := .getCardinality()
	for  := 0;  < ; ++ {
		 := .content[]
		 := uint() >> 6
		 := .bitmap[]
		 :=  &^ (uint64(1) << ( % 64))
		.bitmap[] = 
		.cardinality -= int(( ^ ) >> ( % 64))
	}
	if .cardinality <= arrayDefaultMaxSize {
		return .toArrayContainer()
	}
	return 
}

func ( *bitmapContainer) ( *bitmapContainer) container {
	 := int(popcntMaskSlice(.bitmap, .bitmap))
	if  > arrayDefaultMaxSize {
		 := newBitmapContainer()
		for  := 0;  < len(.bitmap); ++ {
			.bitmap[] = .bitmap[] &^ .bitmap[]
		}
		.cardinality = 
		return 
	}
	 := newArrayContainerSize()
	fillArrayANDNOT(.content, .bitmap, .bitmap)
	return 
}

func ( *bitmapContainer) ( *bitmapContainer) container {
	 := int(popcntMaskSlice(.bitmap, .bitmap))
	for  := 0;  < len(.bitmap); ++ {
		.bitmap[] = .bitmap[] &^ .bitmap[]
	}
	.cardinality = 
	if .getCardinality() <= arrayDefaultMaxSize {
		return .toArrayContainer()
	}
	return 
}

func ( *bitmapContainer) ( uint16) bool { //testbit
	 := uint()
	 := .bitmap[>>6]
	 := uint64(1) << ( & 63)
	return ( & ) != 0
}

func ( *bitmapContainer) ( uint16) uint64 {
	 := uint()
	 := .bitmap[>>6]
	return ( >> ( & 63)) & 1
}

func ( *bitmapContainer) ( *arrayContainer) {
	.cardinality = .getCardinality()
	 := .getCardinality()
	for  := 0;  < ; ++ {
		 := .content[]
		 := int() / 64
		.bitmap[] |= (uint64(1) << uint(%64))
	}
}

func ( *bitmapContainer) ( container) {
	switch x := .(type) {
	case *arrayContainer:
		fill(.bitmap, 0)
		.loadData()

	case *bitmapContainer:
		.cardinality = .cardinality
		copy(.bitmap, .bitmap)

	case *runContainer16:
		.cardinality = len(.iv)
		 := 0
		for ,  := range .iv {
			.cardinality += int(.length)
			resetBitmapRange(.bitmap, , int(.start))
			 = int(.start+.length) + 1
			setBitmapRange(.bitmap, int(.start), )
		}
		resetBitmapRange(.bitmap, , maxCapacity)

	default:
		panic("unsupported container type")
	}
}

func ( *bitmapContainer) () *arrayContainer {
	 := &arrayContainer{}
	.loadData()
	return 
}

func ( *bitmapContainer) ( []uint16) {
	//TODO: rewrite in assembly
	 := 0
	 := 0
	for  := 0;  < len(.bitmap); ++ {
		 := .bitmap[]
		for  != 0 {
			 :=  & -
			[] = uint16(( + int(popcount(-1))))
			 =  + 1
			 ^= 
		}
		 += 64
	}
}

func ( *bitmapContainer) ( uint) int {
	var (
		      =  / 64
		 = uint(len(.bitmap))
	)
	if  >=  {
		return -1
	}
	 := .bitmap[]
	 =  >> uint(%64)
	if  != 0 {
		return int() + countTrailingZeros()
	}
	++
	for ;  < ; ++ {
		if .bitmap[] != 0 {
			return int(*64) + countTrailingZeros(.bitmap[])
		}
	}
	return -1
}

func ( *bitmapContainer) ( int) int {
	if  < 0 {
		return -1
	}
	 :=  / 64
	if  >= len(.bitmap) {
		return -1
	}

	 := .bitmap[]

	 :=  % 64

	 =  << uint(63-)
	if  != 0 {
		return  - countLeadingZeros()
	}
	--
	for ;  >= 0; -- {
		if .bitmap[] != 0 {
			return ( * 64) + 63 - countLeadingZeros(.bitmap[])
		}
	}
	return -1
}

// reference the java implementation
// https://github.com/RoaringBitmap/RoaringBitmap/blob/master/src/main/java/org/roaringbitmap/BitmapContainer.java#L875-L892
func ( *bitmapContainer) () int {
	if .cardinality == 0 {
		return 0
	}

	var  uint64
	 := .bitmap[0]

	for  := 0;  < len(.bitmap)-1; ++ {
		 := 
		 = .bitmap[+1]
		 += popcount((^)&(<<1)) + (( >> 63) &^ )
	}

	 := 
	 += popcount((^) & ( << 1))
	if ( & 0x8000000000000000) != 0 {
		++
	}

	return int()
}

// convert to run or array *if needed*
func ( *bitmapContainer) () container {

	 := .numberOfRuns()

	 := runContainer16SerializedSizeInBytes()
	 := bitmapContainerSizeInBytes()
	 := .getCardinality()
	 := arrayContainerSizeInBytes()

	if  <= minOfInt(, ) {
		return newRunContainer16FromBitmapContainer()
	}
	if  <= arrayDefaultMaxSize {
		return .toArrayContainer()
	}
	return 
}

func newBitmapContainerFromRun( *runContainer16) *bitmapContainer {

	if len(.iv) == 1 {
		return newBitmapContainerwithRange(int(.iv[0].start), int(.iv[0].last()))
	}

	 := newBitmapContainer()
	for  := range .iv {
		setBitmapRange(.bitmap, int(.iv[].start), int(.iv[].last())+1)
		.cardinality += int(.iv[].last()) + 1 - int(.iv[].start)
	}
	//bc.computeCardinality()
	return 
}

func ( *bitmapContainer) () contype {
	return bitmapContype
}

func ( *bitmapContainer) ( uint16) (container, container) {
	var ,  *bitmapContainer

	if .cardinality == 0 {
		return nil, nil
	}

	 := uint32() >> 6
	 := uint32() % 64
	 := uint32(1024) - 

	 = newBitmapContainer()
	if  == 0 {
		copy(.bitmap[:], .bitmap[:])
	} else {
		.bitmap[] = .bitmap[0] << 
		for  := uint32(1);  < ; ++ {
			 := .bitmap[] << 
			 |= .bitmap[-1] >> (64 - )
			.bitmap[+] = 
		}
	}
	.computeCardinality()

	if .cardinality == .cardinality {
		// All elements from bc ended up in low, meaning high will be empty.
		return , nil
	}

	if .cardinality == 0 {
		// low is empty, let's reuse the container for high.
		 = 
		 = nil
	} else {
		// None of the containers will be empty, so allocate both.
		 = newBitmapContainer()
	}

	if  == 0 {
		copy(.bitmap[:], .bitmap[:])
	} else {
		for  := ;  < 1024; ++ {
			 := .bitmap[] << 
			 |= .bitmap[-1] >> (64 - )
			.bitmap[-] = 
		}
		.bitmap[] = .bitmap[1023] >> (64 - )
	}
	.computeCardinality()

	// Ensure proper nil interface.
	if  == nil {
		return nil, 
	}

	return , 
}